home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-I386 / SYSTEM.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  6KB  |  219 lines

  1. #ifndef __ASM_SYSTEM_H
  2. #define __ASM_SYSTEM_H
  3.  
  4. #include <linux/kernel.h>
  5. #include <asm/segment.h>
  6.  
  7. #ifdef __KERNEL__
  8.  
  9. struct task_struct;    /* one of the stranger aspects of C forward declarations.. */
  10. extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
  11.  
  12. /*
  13.  * We do most of the task switching in C, but we need
  14.  * to do the EIP/ESP switch in assembly..
  15.  */
  16. #define switch_to(prev,next) do {                    \
  17.     unsigned long eax, edx, ecx;                    \
  18.     asm volatile("pushl %%ebx\n\t"                    \
  19.              "pushl %%esi\n\t"                    \
  20.              "pushl %%edi\n\t"                    \
  21.              "pushl %%ebp\n\t"                    \
  22.              "movl %%esp,%0\n\t"    /* save ESP */        \
  23.              "movl %5,%%esp\n\t"    /* restore ESP */    \
  24.              "movl $1f,%1\n\t"        /* save EIP */        \
  25.              "pushl %6\n\t"        /* restore EIP */    \
  26.              "jmp __switch_to\n"                \
  27.              "1:\t"                        \
  28.              "popl %%ebp\n\t"                    \
  29.              "popl %%edi\n\t"                    \
  30.              "popl %%esi\n\t"                    \
  31.              "popl %%ebx"                    \
  32.              :"=m" (prev->tss.esp),"=m" (prev->tss.eip),    \
  33.               "=a" (eax), "=d" (edx), "=c" (ecx)        \
  34.              :"m" (next->tss.esp),"m" (next->tss.eip),        \
  35.               "a" (prev), "d" (next));                 \
  36. } while (0)
  37.  
  38. #define _set_base(addr,base) do { unsigned long __pr; \
  39. __asm__ __volatile__ ("movw %%dx,%1\n\t" \
  40.     "rorl $16,%%edx\n\t" \
  41.     "movb %%dl,%2\n\t" \
  42.     "movb %%dh,%3" \
  43.     :"=&d" (__pr) \
  44.     :"m" (*((addr)+2)), \
  45.      "m" (*((addr)+4)), \
  46.      "m" (*((addr)+7)), \
  47.          "0" (base) \
  48.         ); } while(0)
  49.  
  50. #define _set_limit(addr,limit) do { unsigned long __lr; \
  51. __asm__ __volatile__ ("movw %%dx,%1\n\t" \
  52.     "rorl $16,%%edx\n\t" \
  53.     "movb %2,%%dh\n\t" \
  54.     "andb $0xf0,%%dh\n\t" \
  55.     "orb %%dh,%%dl\n\t" \
  56.     "movb %%dl,%2" \
  57.     :"=&d" (__lr) \
  58.     :"m" (*(addr)), \
  59.      "m" (*((addr)+6)), \
  60.      "0" (limit) \
  61.         ); } while(0)
  62.  
  63. #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) )
  64. #define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1)>>12 )
  65.  
  66. static inline unsigned long _get_base(char * addr)
  67. {
  68.     unsigned long __base;
  69.     __asm__("movb %3,%%dh\n\t"
  70.         "movb %2,%%dl\n\t"
  71.         "shll $16,%%edx\n\t"
  72.         "movw %1,%%dx"
  73.         :"=&d" (__base)
  74.         :"m" (*((addr)+2)),
  75.          "m" (*((addr)+4)),
  76.          "m" (*((addr)+7)));
  77.     return __base;
  78. }
  79.  
  80. #define get_base(ldt) _get_base( ((char *)&(ldt)) )
  81.  
  82. /*
  83.  * Load a segment. Fall back on loading the zero
  84.  * segment if something goes wrong..
  85.  */
  86. #define loadsegment(seg,value)            \
  87.     asm volatile("\n"            \
  88.         "1:\t"                \
  89.         "movl %0,%%" #seg "\n"        \
  90.         "2:\n"                \
  91.         ".section .fixup,\"ax\"\n"    \
  92.         "3:\t"                \
  93.         "pushl $0\n\t"            \
  94.         "popl %%" #seg "\n\t"        \
  95.         "jmp 2b\n"            \
  96.         ".previous\n"            \
  97.         ".section __ex_table,\"a\"\n\t"    \
  98.         ".align 4\n\t"            \
  99.         ".long 1b,3b\n"            \
  100.         ".previous"            \
  101.         : :"m" (*(unsigned int *)&(value)))
  102.  
  103. /*
  104.  * Clear and set 'TS' bit respectively
  105.  */
  106. #define clts() __asm__ __volatile__ ("clts")
  107. #define read_cr0() ({ \
  108.     unsigned int __dummy; \
  109.     __asm__( \
  110.         "movl %%cr0,%0\n\t" \
  111.         :"=r" (__dummy)); \
  112.     __dummy; \
  113. })
  114. #define write_cr0(x) \
  115.     __asm__("movl %0,%%cr0": :"r" (x));
  116. #define stts() write_cr0(8 | read_cr0())
  117.  
  118. #endif    /* __KERNEL__ */
  119.  
  120. static inline unsigned long get_limit(unsigned long segment)
  121. {
  122.     unsigned long __limit;
  123.     __asm__("lsll %1,%0"
  124.         :"=r" (__limit):"r" (segment));
  125.     return __limit+1;
  126. }
  127.  
  128. #define nop() __asm__ __volatile__ ("nop")
  129.  
  130. #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
  131. #define tas(ptr) (xchg((ptr),1))
  132.  
  133. struct __xchg_dummy { unsigned long a[100]; };
  134. #define __xg(x) ((struct __xchg_dummy *)(x))
  135.  
  136. /*
  137.  * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
  138.  */
  139. static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
  140. {
  141.     switch (size) {
  142.         case 1:
  143.             __asm__("xchgb %b0,%1"
  144.                 :"=q" (x)
  145.                 :"m" (*__xg(ptr)), "0" (x)
  146.                 :"memory");
  147.             break;
  148.         case 2:
  149.             __asm__("xchgw %w0,%1"
  150.                 :"=r" (x)
  151.                 :"m" (*__xg(ptr)), "0" (x)
  152.                 :"memory");
  153.             break;
  154.         case 4:
  155.             __asm__("xchgl %0,%1"
  156.                 :"=r" (x)
  157.                 :"m" (*__xg(ptr)), "0" (x)
  158.                 :"memory");
  159.             break;
  160.     }
  161.     return x;
  162. }
  163.  
  164. /*
  165.  * Force strict CPU ordering.
  166.  * And yes, this is required on UP too when we're talking
  167.  * to devices.
  168.  *
  169.  * For now, "wmb()" doesn't actually do anything, as all
  170.  * Intel CPU's follow what Intel calls a *Processor Order*,
  171.  * in which all writes are seen in the program order even
  172.  * outside the CPU.
  173.  *
  174.  * I expect future Intel CPU's to have a weaker ordering,
  175.  * but I'd also expect them to finally get their act together
  176.  * and add some real memory barriers if so.
  177.  */
  178. #define mb()     __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
  179. #define rmb()    mb()
  180. #define wmb()    __asm__ __volatile__ ("": : :"memory")
  181.  
  182. /* interrupt control.. */
  183. #define __sti() __asm__ __volatile__ ("sti": : :"memory")
  184. #define __cli() __asm__ __volatile__ ("cli": : :"memory")
  185. #define __save_flags(x) \
  186. __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */ :"memory")
  187. #define __restore_flags(x) \
  188. __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
  189.  
  190.  
  191. #ifdef __SMP__
  192.  
  193. extern void __global_cli(void);
  194. extern void __global_sti(void);
  195. extern unsigned long __global_save_flags(void);
  196. extern void __global_restore_flags(unsigned long);
  197. #define cli() __global_cli()
  198. #define sti() __global_sti()
  199. #define save_flags(x) ((x)=__global_save_flags())
  200. #define restore_flags(x) __global_restore_flags(x)
  201.  
  202. #else
  203.  
  204. #define cli() __cli()
  205. #define sti() __sti()
  206. #define save_flags(x) __save_flags(x)
  207. #define restore_flags(x) __restore_flags(x)
  208.  
  209. #endif
  210.  
  211. /*
  212.  * disable hlt during certain critical i/o operations
  213.  */
  214. #define HAVE_DISABLE_HLT
  215. void disable_hlt(void);
  216. void enable_hlt(void);
  217.  
  218. #endif
  219.